package com.wctj.api.infra.huifu.api;

import com.alibaba.fastjson.JSON;
import com.huifu.adapay.Adapay;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.model.*;
import com.wctj.api.base.enums.ApiCode;
import com.wctj.api.base.enums.PayChannelEnums;
import com.wctj.api.base.exception.CustomException;
import com.wctj.api.base.utils.JsonUtils;
import com.wctj.api.infra.common.api.BasePayService;
import com.wctj.api.infra.common.bean.NoticeParams;
import com.wctj.api.infra.common.bean.PayOrder;
import com.wctj.api.infra.huifu.dto.*;
import com.zgzg.shop.pay.huifu.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 汇付天下
 */
@Slf4j
@Service
public class HuiFuPayService extends BasePayService<HuiFuPayConfigStorage> {

    @Override
    public boolean verify(NoticeParams params) {
        return false;
    }

    /**
     * 初始化配置
     * @param config
     */
    private void init(HuiFuPayConfigStorage config) {
        // debug 模式，开启后有详细的日志
        Adapay.debug = true;
        // prodMode 模式，默认为生产模式，false可以使用mock模式
        Adapay.prodMode = true;

        /**
         * 初始化商户配置，服务器启动前，必须通过该方式初始化商户配置完成
         * apiKey为prod模式的API KEY
         * mockApiKey为mock模式的API KEY
         * rsaPrivateKey为商户发起请求时，用于请求参数加签所需要的RSA私钥
         */
        String apiKey = config.getApiKey();
        String mockApiKey = config.getMockApiKey();
        String rsaPrivateKey = config.getKeyPrivate();
        MerConfig merConfig = new MerConfig();
        merConfig.setApiKey(apiKey);
        merConfig.setApiMockKey(mockApiKey);
        merConfig.setRSAPrivateKey(rsaPrivateKey);

        try {
            Adapay.initWithMerConfig(merConfig);
            log.info("=======initWithMerConfig success =======");
        } catch (Exception e) {
            throw new CustomException(ApiCode.HUIFU_INIT_FAIL);
        }
    }

    private Map<String, Object> builderExpend(String openId,String payChannel) {
        Map<String, Object> expend = new HashMap<>(2);
        if (PayChannelEnums.ADAPAY_WX_LITE.getCode().equalsIgnoreCase(payChannel)
            || PayChannelEnums.ADAPAY_WX_PUB.getCode().equalsIgnoreCase(payChannel)) {
            // 微信用户关注商家公众号的 openid
            expend.put("open_id", openId);
            expend.put("is_raw", 1);
        }
        if (PayChannelEnums.ADAPAY_ALIPAY_LITE.getCode().equalsIgnoreCase(payChannel)) {
            // 买家的支付宝用户 id
            expend.put("buyer_id", openId);
        }
        return expend;
    }

    @Override
    public HuiFuResponsePayInfo toPay(HuiFuPayConfigStorage config, PayOrder payOrder) {
        // 初始化化配置信息
        this.init(config);

        log.info("=======execute payment begin=======");
        //创建支付对象的参数，全部参数请参考 https://docs.adapay.tech/api/index.html
        Map<String, Object> paymentParams = new HashMap<>(10);

        // 设置超时时间 单位毫秒 类型 int
        // adapay_connection_request_timeout 类型 int, 单位：毫秒 ms
        // 非必须, 默认 10000 指从连接池获取连接的 timeout
        paymentParams.put("adapay_connection_request_timeout", 5000);
        // adapay_connect_timeout 单位：毫秒 ms
        // 非必须, 默认 30000 指客户端和服务器建立连接的timeout
        paymentParams.put("adapay_connect_timeout", 5000);
        // adapay_socket_timeout 单位：毫秒 ms
        // 非必须, 默认 30000 指客户端从服务器读取数据的timeout，超出后会抛出SocketTimeOutException
        paymentParams.put("adapay_socket_timeout", 5000);

        paymentParams.put("app_id", config.getAppId());
        paymentParams.put("order_no", payOrder.getOutTradeNo());
        paymentParams.put("pay_channel", config.getPayChannel());

        paymentParams.put("pay_amt", payOrder.getPrice());
        paymentParams.put("goods_title", payOrder.getSubject());
        paymentParams.put("goods_desc", payOrder.getBody());
        paymentParams.put("notify_url", config.getNotifyUrl());
        paymentParams.put("callback_url", config.getCallbackUrl());

        Map<String, Object> expend = this.builderExpend(payOrder.getOpenId(),config.getPayChannel());
        paymentParams.put("expend", expend);

        //调用sdk方法，创建支付，得到支付对象
        Map<String, Object> payment = new HashMap<>();
        try {
            log.info("支付交易，请求参数：{}" , JSON.toJSONString(paymentParams));
            payment = Payment.create(paymentParams);

        } catch (BaseAdaPayException e) {
            e.printStackTrace();
            throw new CustomException(ApiCode.HUIFU_PAYMENT_ORDER_FAIL);
        }
        log.info("支付交易，返回参数：" + JSON.toJSONString(payment));
        log.info("=======execute payment end=======");
        HuiFuResponsePayInfo responsePayInfo =   JsonUtils.readFromString(JSON.toJSONString(payment), HuiFuResponsePayInfo.class);
        // 暂存请求参数
        responsePayInfo.setRequestParams(paymentParams);
        return responsePayInfo;
    }

    /**
     * 根据第三方平台的支付订单号查询第三方平台的支付对象信息
     * @param paymentId
     * @return
     */
    public Map<String, Object> infoByPaymentId(HuiFuPayConfigStorage config,String paymentId) {
        this.init(config);
        // 在完成初始化设置情况下，调用查询方法，获取 Payment 查询结果
        Map<String, Object> response = null;
        try {
            response = Payment.query(paymentId);
        } catch (BaseAdaPayException e) {
            log.error(ApiCode.HUIFU_PAYMENT_ORDER_INFO_FAIL.getMsg(),e);
            throw new CustomException(ApiCode.HUIFU_PAYMENT_ORDER_INFO_FAIL,e.getMessage());
        }
        return response;
    }

    /**
     * 创建实名用户对象
     * @param param
     * @return
     */
    public MemberUserResponse createPersonalUser(HuiFuPayConfigStorage config, MemberUser param) {
        this.init(config);

        Map<String, Object> memberParams = new  HashMap<String, Object>(10);
        memberParams.put("adapay_func_code", "members.realname");
        memberParams.put("member_id", param.getMemberId());
        memberParams.put("app_id", param.getAppId());
        memberParams.put("location", param.getLocation());
        memberParams.put("email", param.getEmail());
        memberParams.put("gender", param.getGender());
        memberParams.put("tel_no", param.getTelNo());
        memberParams.put("user_name", param.getUserName());
        memberParams.put("cert_type", param.getCertType());
        memberParams.put("cert_id", param.getCertId());
        try {
            Map<String, Object> member = AdapayCommon.requestAdapay(memberParams);
            return JsonUtils.readFromString(JSON.toJSONString(member), MemberUserResponse.class);
        } catch (BaseAdaPayException e) {
            e.printStackTrace();
            throw new CustomException(ApiCode.HUIFU_USER_PERSON_CREATE_FAIL);
        }
    }

    /**
     *查询已创建的单个用户对象
     * @param config
     * @param param
     * @return
     */
    public MemberUserResponse queryPersonalUser(HuiFuPayConfigStorage config, QueryMemberUser param) {
        this.init(config);
        Map<String, Object> memberParams = new  HashMap<String, Object>(2);
        memberParams.put("member_id", param.getMemberId());
        memberParams.put("app_id", param.getAppId());
        try {
            Map<String, Object> member = Member.query(memberParams);
            return JsonUtils.readFromString(JSON.toJSONString(member), MemberUserResponse.class);
        } catch (BaseAdaPayException e) {
            e.printStackTrace();
            throw new CustomException(ApiCode.HUIFU_USER_PERSON_QUERY_FAIL);
        }
    }

    /**
     * 查询商户应用 id 下已创建的用户对象列表
     * @param config
     * @param param
     * @return
     */
    public MemberListData listPersonalUser(HuiFuPayConfigStorage config, QueryMemberUser param) {
        init(config);

        Map<String, Object> memberParams = new  HashMap<String, Object>(2);
        memberParams.put("app_id", param.getAppId());

        if(param.getPageIndex()>0) {
            memberParams.put("page_index", param.getPageIndex());
        }
        if (param.getPageSize()>0) {
            memberParams.put("page_size", param.getPageSize());
        }
        if (Objects.nonNull(param.getCreatedGte())) {
            memberParams.put("created_gte", param.getCreatedGte());
        }
        if (Objects.nonNull(param.getCreatedLte())) {
            memberParams.put("created_lte", param.getCreatedLte());
        }
        try {
            Map<String, Object> member = Member.queryList(memberParams);
            return JsonUtils.readFromString(JSON.toJSONString(member), MemberListData.class);
        } catch (BaseAdaPayException e) {
            e.printStackTrace();
            throw new CustomException(ApiCode.HUIFU_USER_PERSON_QUERY_FAIL);
        }
    }

    /**
     * 企业用户（ Member）-创建企业用户对象
     * @param config
     * @param corpUser
     * @return
     */
    public CorpMemberUserResponse createCorpMember(HuiFuPayConfigStorage config, CorpMemberUser corpUser) {
        init(config);

        Map<String, Object> memberParams = new  HashMap<String, Object>(20);
        memberParams.put("member_id", corpUser.getMemberId());
        memberParams.put("app_id", corpUser.getAppId());
        memberParams.put("order_no",corpUser.getMemberOrderNum());
        memberParams.put("social_credit_code_expires", corpUser.getSocialCreditCodeExpires());
        memberParams.put("business_scope", corpUser.getBusinessScope());
        memberParams.put("name", corpUser.getName());
        memberParams.put("prov_code", corpUser.getProvCode());
        memberParams.put("area_code", corpUser.getAreaCode());
        memberParams.put("social_credit_code", corpUser.getSocialCreditCode());
        memberParams.put("legal_person", corpUser.getLegalPerson());
        memberParams.put("legal_cert_id", corpUser.getLegalCertId());
        memberParams.put("legal_cert_id_expires", corpUser.getLegalCertIdExpires());
        memberParams.put("legal_mp", corpUser.getLegalMp());
        memberParams.put("address", corpUser.getAddress());
        memberParams.put("zip_code", corpUser.getZipCode());
        memberParams.put("telphone", corpUser.getTelphone());
        memberParams.put("email" , corpUser.getEmail());
        memberParams.put("bank_code", corpUser.getBankCode());
        memberParams.put("bank_acct_type", corpUser.getBankAcctType());
        memberParams.put("card_no", corpUser.getCardNo());
        memberParams.put("card_name", corpUser.getCardName());
        File file = corpUser.getAttachFile();
//        // 先放绝对路径 ,后面如果有不对再调整
//        memberParams.put("attach_file", file);
        memberParams.put("notify_url", corpUser.getNotifyUrl());
        try {
            Map<String, Object> member = CorpMember.create(memberParams,file);
            return JsonUtils.readFromString(JSON.toJSONString(member), CorpMemberUserResponse.class);
        } catch (BaseAdaPayException e) {
            e.printStackTrace();
            throw new CustomException(ApiCode.HUIFU_USER_CORP_CREATE_FAIL);
        }

    }
}
